﻿using System;
using System.Collections.Generic;
using LogSystem;
using UnityEngine;
using UnityEngine.U2D;
using Yoozoo.Framework.Core;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace com.yoozoo.gta.Gameplay.Common.SpriteInstance
{
    public class FlagSpriteMgr: Singleton<FlagSpriteMgr>
    {
        private int MainTextureId = -1;
        private int MainSTId;
        private Dictionary<string, Sprite> _cacheSprite = null;
        private Dictionary<string, MaterialPropertyBlock> _cacheMaterialPropertyBlocks = null;
        private Texture _texture;
        private bool isInit = false;
        public void SetSpriteAtlas(SpriteAtlas spriteAtlas)
        {
            
            if (!isInit)
            {
                MainTextureId = Shader.PropertyToID("_MainTex");
                MainSTId = Shader.PropertyToID("_MainTex_ST");
            }
            Sprite[] sprites = new Sprite[spriteAtlas.spriteCount];
            var spCount = spriteAtlas.GetSprites(sprites);
            if (sprites.Length > 0)
            {
                _texture = sprites[0].texture;
                _cacheSprite = new Dictionary<string, Sprite>(spCount);
                _cacheMaterialPropertyBlocks = new Dictionary<string, MaterialPropertyBlock>(spCount);

                isInit = true;
                for (int i = 0; i < spCount; i++)
                {
                    var sp = sprites[i];
                    cacheSpriteAndMaterialPB(sp);
                }
            }
        }

        private void cacheSpriteAndMaterialPB(Sprite sp)
        {
            var spName = sp.name.Replace("(Clone)", String.Empty);
            if (!_cacheSprite.TryAdd(spName, sp))
            {
                Debug.LogErrorFormat("has same key = {0}",spName);
                return;
            }
               
            var m_block = new MaterialPropertyBlock();
            var spRect = sp.textureRect;
            Vector4 v4 = new Vector4(spRect.width/sp.texture.width,spRect.height/sp.texture.height,
                spRect.x/sp.texture.width, spRect.y/sp.texture.height);
            m_block.SetVector(MainSTId,v4);

            _cacheMaterialPropertyBlocks.Add(spName, m_block);
        }

        public void loadSpriteAtlas(string assetPath)
        {
            if (!isInit)
            {
                MainTextureId = Shader.PropertyToID("_MainTex");
                MainSTId = Shader.PropertyToID("_MainTex_ST");
            }
            UMTResource.LoadAsset(assetPath, (name, asset, duration, data) =>
            {
                object[] allSubAssets = UMTResource.GetAllSubAssets(asset);
                var len = allSubAssets.Length;
                if (len > 1)
                {
                    _cacheSprite = new Dictionary<string, Sprite>(len - 1);
                    _cacheMaterialPropertyBlocks = new Dictionary<string, MaterialPropertyBlock>(len-1);
                }
                for (int i = 0; i < len; i++)
                {
                     var subAsset = allSubAssets[i] as Sprite;
                     if (subAsset)
                     {
                        cacheSpriteAndMaterialPB(subAsset);
                     }
                }
                UMTResource.Resource.UnloadResource(asset);
            }, (name, status, message, data) =>
            {
                Debug.Log(LogModule._Default_, $"LoadFlagAtlas failed: {name}");
            });
        }
        public void ChangeFlag(MeshRenderer mr,string name)    
        {
            if (_cacheMaterialPropertyBlocks == null)
            {
                Debug.LogError("FlagSpriteAtlas Not  init");
                return;
            }

#if UNITY_EDITOR
            var sp = GetFlagSprite(name);
            mr.material.mainTexture = sp.texture;
#else        
            mr.sharedMaterial.mainTexture = _texture;
#endif
            
            MaterialPropertyBlock m_block;
            if (_cacheMaterialPropertyBlocks.TryGetValue(name, out m_block))
            {
                mr.SetPropertyBlock(m_block);
            }
            else
            {
                Debug.LogWarningFormat("not found flag {0}",name);
            }
        }

        public Sprite GetFlagSprite(string name)
        {
            if (isInit)
            {
                Sprite sp;
                if (_cacheSprite.TryGetValue(name, out sp))
                {
                    return sp;
                }
                else
                {
                    Debug.LogWarningFormat("not find flag Sprite {0}",name);
                }
            }

            return null;
        }
        public void Dispose()
        {
            if (isInit)
            {
                _texture = null;
                _cacheSprite = null;
                _cacheMaterialPropertyBlocks = null;
            }
        }
    }
}